#include "FuncionesUtiles.h"
#include "claves/Key.h"
#include "indices/arbol/ManipuladorVector.h"
#include "Constantes.h"
#include "indices/arbol/BloqueArbol.h"

cantBytes bytesToCantBytes(const Bytes& bytes) {

	cantBytes numero;

	if ((bytes.getTamanio() != LONGITUD_CANT_BYTES)) {
		cerr << "Tamanio de Bytes incorrecta en funcion bytesToCantBytes";
		return 0;
	}

	memcpy(&numero,bytes.toString().c_str(),LONGITUD_CANT_BYTES);

	return numero;
}

string convertirBytesOffsetAString(const offset &off) {

	string str;
	char aux[LONGITUD_CANT_BYTES];
	memcpy(aux,&off,LONGITUD_CANT_BYTES);
	str.append(aux,LONGITUD_CANT_BYTES);

	return str;
}

int stringToInt(const string &string) {
	int aux;
	stringstream ss(string);

	ss >> aux;
	return aux;
}

unsigned int stringToUInt(const string &string) {
	unsigned int aux;
	stringstream ss(string);

	ss >> aux;
	return aux;
}

string intToString(const int entero) {
	stringstream ss;

	ss << entero;
	return ss.str();
}

bool stringToBool(const string &string) {
	bool aux;
	stringstream ss(string);

	ss >> aux;
	return aux;
}

string boolToString(const bool booleano) {
	stringstream ss;

	ss << booleano;
	return ss.str();
}

string toUpperCase(const string &dato) {

	string aux;

	for ( unsigned int i = 0 ; i < dato.size() ; i++ ){

		char letraActual = (char)toupper(dato[i]);
		aux += letraActual;
	}
	return aux;
}

string quitarLetra(char letra,const string &dato) {

	string aux;

	for ( unsigned int i = 0 ; i < dato.size() ; i++) {

		if ( dato[i] != letra) {
			aux += dato[i];
		}
	}
	return aux;
}


Bytes crearByteNulo() {
	char charNulo = 0;
	string stringNulo;
	stringNulo += charNulo;
	return Bytes(stringNulo);
}

Bytes crearBytesNulos(cantBytes cantidad) {
	Bytes bytesNulos;

	for (cantBytes i = 0; i < cantidad; i++) {
		bytesNulos.agregarAlFinal(crearByteNulo());
	}

	return bytesNulos;
}

offset obtenerOffsetPorBits(string s,cantBytes cantidadBits) {

	offset offsetBits = 0;
	unsigned int i;
	int vec[8];

	for (i = 0; i < s.size(); i++) {

		unsigned char aux = s[i];
        bitsSeteados(aux, vec);

        unsigned int j;

        for (j = 0; ((j < 8) &&((i*8 +  j) < cantidadBits)); j++) {
        	offsetBits += vec[j]*pow(2,j + i*8);
        }
        cout << endl;
        if (i*8 >= cantidadBits) {
        	break;
        }
	}

	return offsetBits;
}


void bitsSeteados(const unsigned char byte, int *vector) {
	unsigned char a = byte;

	for(int i = 7; 0 <= i ; i--){
		vector[i] = a % 2;
		a = a / 2;
	}
}


unsigned int pow(unsigned int base,unsigned int exponente) {

	if (exponente == 0) {
		return 1;
	}

	unsigned int resultado = 1;

	for (unsigned int i = 0; i < exponente ; i++) {
		resultado *= base;
	}

	return resultado;
}

void bitsSeteados(offset dato, int *vector) {

	for(int i = 31; 0 <= i ; i--){
		vector[i] = dato % 2;
		dato = dato / 2;
	}
}

string deOffsetAStringBinario(offset dato,cantBytes cantBits) {

	string cadenaConvertida;
	int* vector = new int[32];

	bitsSeteados(dato,vector);

	for (int i = 0 ; i < 32; i++) {

		if (vector[i]) {
			cadenaConvertida += '1';
		} else {
			cadenaConvertida += '0';
		}
	}

	delete vector;

	string cadenaRetornada;

	for (cantBytes i = 0; i < cantBits; i++) {

		cadenaRetornada = cadenaConvertida[31 - i] + cadenaRetornada;
	}

	return cadenaRetornada;
}




